local StellarBars = CreateFrame("Frame", "StellarBars", UIParent)
local self = StellarBars
StellarBars:SetScript("OnEvent", function(this, event, ...)
	this[event](this, ...)
end)

-- LIBRARIES
local smed = LibStub("LibSharedMedia-3.0")
local lbf = LibStub("LibButtonFacade", true)  -- optional

-- GLOBAL -> LOCAL
local _G = getfenv(0)
local MainMenuBar, VehicleMenuBar = MainMenuBar, VehicleMenuBar
local MultiBarBottomLeft, MultiBarBottomRight, MultiBarLeft, MultiBarRight = MultiBarBottomLeft, MultiBarBottomRight, MultiBarLeft, MultiBarRight
local ShapeshiftBarFrame, PetActionBarFrame = ShapeshiftBarFrame, PetActionBarFrame
local MainMenuExpBar = MainMenuExpBar
local ReputationWatchBar, ReputationWatchStatusBar, ReputationWatchStatusBarText = ReputationWatchBar, ReputationWatchStatusBar, ReputationWatchStatusBarText
local GetNumShapeshiftForms, InCombatLockdown = GetNumShapeshiftForms, InCombatLockdown
local IsUsableAction, IsActionInRange, HasAction = IsUsableAction, IsActionInRange, HasAction
local oSetPoint, oSetVertexColor = MainMenuBar.SetPoint, ActionButton1Icon.SetVertexColor
local MainMenuBarArtFrame = MainMenuBarArtFrame


-- LOCAL VARS
local db, opts, lbfgroup, repupdated
local backdrop = { bgFile = "Interface\\Buttons\\WHITE8X8", }
local skin = lbf and {  -- LibButtonFacade skin
	Template = "Blizzard",
	Normal = { Hide = true, },
	Backdrop = { Width = 42, Height = 42, Texture = "Interface\\AddOns\\StellarBars\\backdrop", },
	Icon = { Width = 36, Height = 36, TexCoords = { 0.07, 0.93, 0.07, 0.93, }, },
} or { bgFile = "Interface\\AddOns\\StellarBars\\backdrop", }
local buttons = {
	"ActionButton%d", "BonusActionButton%d", "ShapeshiftButton%d", "PetActionButton%d", "PossessButton%d",
	"MultiBarBottomLeftButton%d", "MultiBarBottomRightButton%d", "MultiBarLeftButton%d", "MultiBarRightButton%d",
	"CharacterBag%dSlot", "VehicleMenuBarActionButton%d",
}
local mainexpshown, repshown

-- LOCAL FUNCS
local nothing = function() end
local function FullAdjust(frame, p, rt, rp, x, y)
	local a,b,c,d,e = frame:GetPoint()
	frame:ClearAllPoints()
	oSetPoint(frame, p or a, rt or b, rp or c, x or d, y or e)
end
local function appendpercent(barframe, textframe)
	local vmin, vmax = barframe:GetMinMaxValues()
	local otext = textframe:GetText() or ""
	local perc = barframe:GetValue() * 100 / (vmax - vmin)
	textframe:SetFormattedText("%s (%0.1f%%)", otext, perc)
end
local function lActionButton_UpdateUsable(self)
	local page = self.action
	if not HasAction(page) then return end
	local icon = _G[self:GetName().."Icon"]
	local isUsable, notEnoughMana = IsUsableAction(page)
	if isUsable then
		if IsActionInRange(page) ~= 0 then
			oSetVertexColor(icon, 1, 1, 1)
		else
			oSetVertexColor(icon, 1, 0.4, 0.4)
		end
	elseif notEnoughMana then
		oSetVertexColor(icon, 0.4, 0.4, 1)
	else
		oSetVertexColor(icon, 0.4, 0.4, 0.4)
	end
end
local function lActionButton_OnUpdate(self, elapsed)
	local e = self.stelap
	if not e then
		local hk = _G[self:GetName().."HotKey"]
		if hk then
			hk:SetVertexColor(1, 1, 1, 1)
			hk.SetVertexColor = nothing
		end
	end
	e = (e or 0) + elapsed
	if e > 0.3 and self.action then
		e = 0
		lActionButton_UpdateUsable(self)
	end
	self.stelap = e
end
local function updatepetbar()
	if InCombatLockdown() then return end
	if GetNumShapeshiftForms() > 0 then
		PetActionButton1:SetPoint("BOTTOMLEFT", PetActionBarFrame, "BOTTOMLEFT", 40 - MainMenuBar:GetLeft(), 2)
	else
		PetActionButton1:SetPoint("BOTTOMLEFT", PetActionBarFrame, "BOTTOMLEFT", 36, 2)
	end
end
local function UpdatePositions()
	if InCombatLockdown() then 
		return self:RegisterEvent("PLAYER_REGEN_ENABLED")
	else
		self:UnregisterEvent("PLAYER_REGEN_ENABLED")
	end
	local sx, sy = (-7 + (db.sidex or 0)) / db.scale, (98 + (db.sidey or 0)) / db.scale
	oSetPoint(MultiBarRight, "BOTTOMRIGHT", UIParent, "BOTTOMRIGHT", sx, sy)
	oSetPoint(MultiBarRight, "BOTTOM", UIParent, "BOTTOM", sx + 38, sy)
	oSetPoint(MultiBarRight, "RIGHT", UIParent, "RIGHT", sx, sy + 250)
	
	local mx, my = (db.mainx or 0) / db.scale, (db.mainy or 0) / db.scale
	oSetPoint(MainMenuBar, "BOTTOMLEFT", UIParent, "BOTTOM", -512 + mx, my)
	oSetPoint(MainMenuBar, "BOTTOMRIGHT", UIParent, "BOTTOM", 512 + mx, my)
	
	local adj = ((mainexpshown and repshown) and 22) or (((mainexpshown or repshown) and 13)) or 8
	MainMenuBarArtFrame:SetPoint("TOPLEFT", MainMenuBar, "TOPLEFT", 0, adj)
	MainMenuBarArtFrame:SetPoint("BOTTOMRIGHT", MainMenuBar, "BOTTOMRIGHT", 0, adj)
	updatepetbar()
end
local function UpdateLook()
	if InCombatLockdown() then return end
	local s = db.scale
	local a = db.alpha or 1
	MainMenuBar:SetScale(s) MultiBarBottomLeft:SetScale(s) MultiBarBottomRight:SetScale(s) MultiBarRight:SetScale(s) MultiBarLeft:SetScale(s) VehicleMenuBar:SetScale(s)
	MainMenuBar:SetAlpha(a) MultiBarBottomLeft:SetAlpha(a) MultiBarBottomRight:SetAlpha(a) MultiBarRight:SetAlpha(a) MultiBarLeft:SetAlpha(a) VehicleMenuBar:SetAlpha(a)
	
	local t = smed:Fetch("statusbar", db.texture)
	MainMenuExpBar:SetStatusBarTexture(t)
	ReputationWatchStatusBar:SetStatusBarTexture(t)
	
	local font = smed:Fetch("font", db.font)
	for _,value in ipairs(buttons) do
		for i = 0, 12, 1 do
			local hotkey, count, name = _G[format(value.."HotKey", i)], _G[format(value.."Count", i)], _G[format(value.."Name", i)]
			if hotkey then hotkey:SetFont(font, 12, "OUTLINE") end
			if count then count:SetFont(font, 10, "OUTLINE") end
			if name then name:SetFont(font, 10) end
		end
	end
	if MainMenuBarBackpackButtonCount then MainMenuBarBackpackButtonCount:SetFont(font, 10, "OUTLINE") end
	if MainMenuBarBackpackButtonStock then MainMenuBarBackpackButtonStock:SetFont(font, 10, "OUTLINE") end
	for i = 0, 3, 1 do
		local count, stock = _G["CharacterBag"..i.."SlotCount"], _G["CharacterBag"..i.."SlotStock"]
		if count then count:SetFont(font, 10, "OUTLINE") end
		if stock then stock:SetFont(font, 10) end
	end
	MainMenuBarExpText:SetFont(font, 12)
	ReputationWatchStatusBarText:SetFont(font, 12)
end


StellarBars:RegisterEvent("ADDON_LOADED")
-------------------------------------
function StellarBars:ADDON_LOADED(a1)
-------------------------------------
	if a1 ~= "StellarBars" then return end
	self:UnregisterEvent("ADDON_LOADED")
	
	StellarBarsDB = StellarBarsDB or {}
	db = (StellarBarsDB.profiles and StellarBarsDB.profiles.Default) or StellarBarsDB
	if db.dbinit ~= 1 then
		db.dbinit = nil
		for k,v in pairs({
			scale = 0.9,
			alpha = 1,
			mainx = 0, mainy = 1,
			sidex = 0, sidey = 0,
			r = 0, g = 0, b = 0, a = 0.9,
			font = "Friz Quadrata TT",
			texture = "Blizzard",
			skin = "StellarBars",
			oor = true, selfcast = true,
			dbinit = 1,
		}) do
			db[k] = (db[k] ~= nil and db[k]) or v
		end
	end
	db.font = db.font or "Friz Quadrata TT"
	
	SlashCmdList.STELLARBARS = self.ShowOptions
	SLASH_STELLARBARS1, SLASH_STELLARBARS2 = "/stellarbars", "/stellarbar"

	local SetPoints = function(this, lp, lrt, lrp, lx, ly, rp, rrt, rrp, rx, ry)
		this:SetPoint(lp, lrt, lrp, lx, ly)
		this:SetPoint(rp, rrt, rrp, rx, ry)
	end
	
	local panel = CreateFrame("Frame")
	panel.name = "StellarBars"
	panel:SetScript("OnShow", function(this)
		local t1 = this:CreateFontString(nil, "ARTWORK")
		t1:SetFontObject(GameFontNormalLarge)
		t1:SetJustifyH("LEFT") 
		t1:SetJustifyV("TOP")
		t1:SetPoint("TOPLEFT", 16, -16)
		t1:SetText(this.name)
		
		local t2 = this:CreateFontString(nil, "ARTWORK")
		t2:SetFontObject(GameFontHighlightSmall)
		t2:SetJustifyH("LEFT") 
		t2:SetJustifyV("TOP")
		t2:SetHeight(43)
		SetPoints(t2, "TOPLEFT", t1, "BOTTOMLEFT", 0, -8, "RIGHT", this, "RIGHT", -32, 0)
		t2:SetNonSpaceWrap(true)
		local function GetInfo(field)
			return GetAddOnMetadata("StellarBars", field) or "N/A"
		end
		t2:SetFormattedText("Notes: %s\nAuthor: %s\nVersion: %s", GetInfo("Notes"), GetInfo("Author"), GetInfo("Version"))
	
		local b = CreateFrame("Button", nil, this, "UIPanelButtonTemplate")
		b:SetWidth(120)
		b:SetHeight(20)
		b:SetText("Options Menu")
		b:SetScript("OnClick", self.ShowOptions)
		b:SetPoint("TOPLEFT", t2, "BOTTOMLEFT", -2, -8)
		this:SetScript("OnShow", nil)
	end)
	InterfaceOptions_AddCategory(panel)

	-- hide/disable some stuff
	local stuffToHide = {
		"MainMenuXPBarTexture0", "MainMenuXPBarTexture1", "MainMenuXPBarTexture2", "MainMenuXPBarTexture3",
		"ReputationWatchBarTexture0", "ReputationWatchBarTexture1", "ReputationWatchBarTexture2", "ReputationWatchBarTexture3",
		"ReputationXPBarTexture0", "ReputationXPBarTexture1", "ReputationXPBarTexture2", "ReputationXPBarTexture3",
		"MainMenuBarTexture0", "MainMenuBarTexture1", "MainMenuBarTexture2", "MainMenuBarTexture3",
		"MainMenuBarLeftEndCap", "MainMenuBarRightEndCap",
		"ShapeshiftBarLeft", "ShapeshiftBarRight", "ShapeshiftBarMiddle",
		"MainMenuMaxLevelBar0", "MainMenuMaxLevelBar1", "MainMenuMaxLevelBar2", "MainMenuMaxLevelBar3",
		"BonusActionBarTexture0", "BonusActionBarTexture1",
		"SlidingActionBarTexture0", "SlidingActionBarTexture1",
		"PossessBackground1", "PossessBackground2",
	}
	for index,value in pairs(stuffToHide) do
		_G[value]:SetAlpha(0)
		_G[value]:Hide()
	end
	stuffToHide = nil

	hooksecurefunc("ActionButton_Update", function(this) 
		if not lbf or db.skin ~= "Blizzard" then 
			this:SetNormalTexture("") 
		end 
	end)

	hooksecurefunc("PetActionBar_Update", function()
		for i = 1, 10, 1 do
			_G["PetActionButton"..i]:SetNormalTexture("")
		end
	end)
	
	-- hides main actionbar when bonusactionbar appears
	local function HideMainAction()
		for i = 1, 12, 1 do 
			_G["ActionButton"..i]:SetAlpha(0)
		end
	end
	hooksecurefunc("ShowBonusActionBar", HideMainAction)
	hooksecurefunc("HideBonusActionBar", function() 
		for i = 1, 12, 1 do 
			_G["ActionButton"..i]:SetAlpha(1)
		end
	end)
	if BonusActionBarFrame:IsShown() then HideMainAction() end

	-- skin the buttons
	local r, g, b, a = db.r, db.g, db.b, (db.a or 1)
	local SkinButton
	if lbf then  -- use buttonfacade to skin
		skin.Backdrop.Color = skin.Backdrop.Color or { r, g, b, a, }
		lbf:AddSkin("StellarBars", skin, true) 
		lbfgroup = lbf:Group("StellarBars", "All")
		lbfgroup:Skin(db.skin or "StellarBars", true, true)
		SkinButton = function(button)
			local fbg = CreateFrame("Frame", nil, button)
			fbg:SetFrameLevel(button:GetFrameLevel() - 1)
			fbg:EnableMouse(true)
			SetPoints(fbg, "TOPLEFT", button, "TOPLEFT", -3, 3, "BOTTOMRIGHT", button, "BOTTOMRIGHT", 3, -3)
			lbfgroup:AddButton(button)
		end
		lbf:RegisterSkinCallback("StellarBars", function(_, SkinID, Gloss, Backdrop, Group, Button, Colors)
			if SkinID == "StellarBars" and Colors and Colors.Backdrop then
				db.r, db.g, db.b, db.a = unpack(Colors.Backdrop)
			end
			db.skin = SkinID
		end)
	else  -- default skinning
		SkinButton = function(button)
			local name = button:GetName()
			local fbg = CreateFrame("Frame", nil, button)
			fbg:SetFrameLevel(button:GetFrameLevel() - 1)
			fbg:SetBackdrop(skin)
			fbg:SetBackdropColor(r, g, b, a)
			fbg:EnableMouse(true)
			SetPoints(fbg, "TOPLEFT", button, "TOPLEFT", -3, 3, "BOTTOMRIGHT", button, "BOTTOMRIGHT", 3, -3)
			_G[name.."Icon"]:SetTexCoord(0.07, 0.93, 0.07, 0.93)
			button:SetNormalTexture("")
			button.sbbutton = fbg
		end
	end

	local function handlebag(name, adj)  -- adjust bag buttons
		local button = _G[name]
		button:SetWidth(button:GetWidth() + adj)
		button:SetHeight(button:GetHeight() + adj)
		setglobal(name.."Icon", _G[name.."IconTexture"])  -- ButtonFacade workaround
	end
	handlebag("MainMenuBarBackpackButton", -2)
	MainMenuBarBackpackButton:SetPoint("BOTTOMRIGHT", -6, 4)
	for i = 0, 3, 1 do
		handlebag("CharacterBag"..i.."Slot", 0)
	end
	handlebag = nil

	for _,value in pairs(buttons) do
		for i = 0, 12, 1 do
			local butt = _G[format(value, i)]
			if butt then
				if value == "ActionButton%d" or value == "BonusActionButton%d" then  -- keeps empty buttons shown
					butt.showgrid = 10
					butt:SetAttribute("showgrid", 10)
					butt:Show()
					butt:UnregisterEvent("ACTIONBAR_SHOWGRID")
					butt:UnregisterEvent("ACTIONBAR_HIDEGRID")
				end
				local butthk = _G[format(value.."HotKey", i)]
				if butthk and value ~= "VehicleMenuBarActionButton%d" then
					butthk:ClearAllPoints()
					butthk:SetPoint("TOPRIGHT", butt, "TOPRIGHT", 1, 1)
				end
				SkinButton(butt)
			end
		end
	end
	SkinButton(MainMenuBarBackpackButton)
	SkinButton = nil
	
	MainMenuBar:EnableMouse(false)
	BonusActionBarFrame:EnableMouse(false)
	BonusActionBarFrame:SetParent(MainMenuBarArtFrame)
	BonusActionBarFrame:SetFrameStrata("HIGH")
	
	-- adds a background behind the etc buttons
	local newBG = CreateFrame("Button", "StellarMiscBG", MainMenuBar)
	SetPoints(newBG, "TOPLEFT", ActionBarUpButton, "TOPLEFT", 4, -5, "BOTTOMRIGHT", KeyRingButton, "BOTTOMRIGHT", 1, 0)
	newBG:SetBackdrop(backdrop)
	newBG:SetBackdropColor(r, g, b, a * 0.8)
	
	-- adjust experience bars
	local function createticks(parent)
		local t = parent:CreateTexture(nil, "OVERLAY")
		t:SetTexture("Interface\\AddOns\\StellarBars\\ticks")
		t:SetVertexColor(1, 1, 1, 0.9)
		return t
	end
	local function alterexpbar(f, ftext)
		f:SetHeight(8)
		f:SetWidth(f:GetWidth() - 16)
		SetPoints(createticks(f), "TOPLEFT", f, "TOPLEFT", 0, 0, "BOTTOMRIGHT", f, "BOTTOM", 0, 0)
		SetPoints(createticks(f), "TOPLEFT", f, "TOP", -1, 0, "BOTTOMRIGHT", f, "BOTTOMRIGHT", 0, 0)
		ftext:SetVertexColor(1, 1, 1, 1)
		ftext:SetShadowOffset(-1, -1)
	end
	
	-- experience bar
	hooksecurefunc("MainMenuExpBar_Update", function()
		if MainMenuExpBar.TextString:IsShown() then
			appendpercent(MainMenuExpBar, MainMenuExpBar.TextString)
		end
	end)
	MainMenuExpBar:HookScript("OnEnter", function(this)
		appendpercent(this, this.TextString) 
	end)
	alterexpbar(MainMenuExpBar, MainMenuBarExpText)
	mainexpshown = MainMenuExpBar:IsShown()
	
	-- reputation bar
	hooksecurefunc("ReputationWatchBar_Update", function(...)
		ReputationWatchStatusBar:SetHeight(8)
		if ReputationWatchStatusBarText:IsShown() then
			appendpercent(ReputationWatchStatusBar, ReputationWatchStatusBarText)
		else
			repupdated = true
		end
		local doupdate = false
		if MainMenuExpBar:IsShown() then
			if not mainexpshown then
				mainexpshown, doupdate = true, true
			end
		elseif mainexpshown then
			mainexpshown, doupdate = false, true
		end
		if ReputationWatchBar:IsShown() then
			if not repshown then
				repshown, doupdate = true, true
			end
		elseif repshown then
			repshown, doupdate = false, true
		end
		if doupdate then UpdatePositions() end
		FullAdjust(ReputationWatchBar, "TOP", (mainexpshown and MainMenuExpBar) or MainMenuBarArtFrame, "BOTTOM", nil, -1)
	end)
	ReputationWatchBar:HookScript("OnEnter", function(this) 
		if not repupdated then return end
		appendpercent(ReputationWatchStatusBar, ReputationWatchStatusBarText) 
		repupdated = false
	end)
	alterexpbar(ReputationWatchStatusBar, ReputationWatchStatusBarText)
	ReputationWatchBar:SetWidth(ReputationWatchBar:GetWidth() - 16)
	ExhaustionLevelFillBar:SetHeight(8)
	ExhaustionTick:SetHeight(26)
	ExhaustionTick:SetWidth(26)
	repshown = ReputationWatchBar:IsShown()
	
	UIPARENT_MANAGED_FRAME_POSITIONS["MultiBarBottomLeft"] = nil
	UIPARENT_MANAGED_FRAME_POSITIONS["MultiBarRight"] = nil
	
	FullAdjust(MainMenuExpBar, "TOP", MainMenuBarArtFrame, "BOTTOM")
	FullAdjust(MultiBarBottomLeft, "BOTTOMLEFT", MainMenuBarArtFrame, "TOPLEFT", 8, -7)
	FullAdjust(MultiBarBottomRight, "BOTTOMRIGHT", MainMenuBarArtFrame, "TOPRIGHT", -4, -7)
	FullAdjust(BonusActionBarFrame, "TOPLEFT", MainMenuBarArtFrame, "BOTTOMLEFT", 40, 0)
	
	-- hack vehicle bar so that it is positioned relative to MainMenuBar
	VehicleMenuBar:SetPoint("BOTTOMLEFT", MainMenuBar, "BOTTOMLEFT", 27, 0)
	VehicleMenuBar:SetPoint("BOTTOMRIGHT", MainMenuBar, "BOTTOMRIGHT", -27, 0)
	local function adjvehicleskin(this)
		if not this then return end
		local p, rt, rp, x, y = this:GetPoint()
		if strfind(p or "blah", "LEFT") and this:GetParent() == rt then
			oSetPoint(this, p, rt, rp, x + (970 - VehicleMenuBar:GetWidth()), y)
		end
	end
	local function UpdateVehicleSkins()
		for i=1, 4, 1 do
			adjvehicleskin(_G["VehicleMenuBarArtFrameBACKGROUND"..i])
		end
		for i=1, 8, 1 do
			adjvehicleskin(_G["VehicleMenuBarArtFrameBORDER"..i])
		end
		for i=1, 11, 1 do
			adjvehicleskin(_G["VehicleMenuBarArtFrameARTWORK"..i])
		end
		for i=1, 5, 1 do
			adjvehicleskin(_G["VehicleMenuBarArtFrameOVERLAY"..i])
		end
		adjvehicleskin(VehicleMenuBarHealthBar)
	end
	hooksecurefunc("VehicleMenuBar_SetSkin", UpdateVehicleSkins)
	UpdateVehicleSkins()

	self:RegisterEvent("PLAYER_ENTERING_WORLD")
	self.PLAYER_REGEN_ENABLED = UpdatePositions
	self.PLAYER_ENTERING_WORLD = UpdatePositions
	hooksecurefunc(MainMenuBar, "SetPoint", UpdatePositions)
	hooksecurefunc(MultiBarRight, "SetPoint", UpdatePositions)
	hooksecurefunc("InterfaceOptionsFrameOkay_OnClick", UpdatePositions)
	
	PetActionBarFrame:EnableMouse(false)
	PetActionBar_UpdatePositionValues()
	updatepetbar()
	hooksecurefunc(PetActionBarFrame, "SetPoint", updatepetbar)
	
	
	StellarMiscBG:RegisterForClicks("RightButtonUp")
	StellarMiscBG:SetScript("OnClick", self.ShowOptions)
	
	if db.selfcast then  -- adds right-click self-casting
		MainMenuBarArtFrame:SetAttribute("unit2", "player")
		MultiBarBottomLeft:SetAttribute("unit2", "player")
		MultiBarBottomRight:SetAttribute("unit2", "player")
		MultiBarLeft:SetAttribute("unit2", "player")
		MultiBarRight:SetAttribute("unit2", "player")
	end
	if db.oor then  -- out of range/mana recoloring
		ActionButton_OnUpdate = lActionButton_OnUpdate
		ActionButton_UpdateUsable = lActionButton_UpdateUsable
	end
	if not smed:IsValid("font", db.font) or not smed:IsValid("statusbar", db.texture) then
		smed.RegisterCallback(self, "LibSharedMedia_Registered", function(event, mediatype, key)
			if key == db.font or key == db.texture then UpdateLook() end
		end) 
	end
	
	UpdateLook()
	UpdatePositions()
	self.ADDON_LOADED = nil
end

local StellarBarsDD, mainmover, sidemover
local info = { }
local offsetvalue, offsetcount, lastb
function StellarBars.ShowOptions(a1)
	if not StellarBarsDD then
		StellarBarsDD = CreateFrame("Frame", "StellarBarsDD", UIParent)
		StellarBarsDD.displayMode = "MENU"
		
		hooksecurefunc("ToggleDropDownMenu", function(...) lastb = select(8, ...) end)
		local function HideCheck(b)
			if b and b.GetName and _G[b:GetName().."Check"] then
				_G[b:GetName().."Check"]:Hide()
			end
		end
		local function RefreshMenu(b)
			local tb = _G[gsub(lastb:GetName(), "ExpandArrow", "")]
			CloseDropDownMenus(b:GetParent():GetID())
			ToggleDropDownMenu(b:GetParent():GetID(), tb.value, nil, nil, nil, nil, tb.menuList, tb)
		end
		local function Set(b, a1, a2)
			if not a1 then return end
			if (a1 == "less" or a1 == "more") and lastb then
				local off = (a1 == "less" and -8) or 8
				if offsetvalue == a2 then
					offsetcount = offsetcount + off
				else
					offsetvalue, offsetcount = a2, off
				end
				RefreshMenu(b)
			elseif a1 == "unlock" then
				if not mainmover then
					local function CreateMover(p, which, p1, rp1, x1, y1, p2, rp2, x2, y2)
						local mm = CreateFrame("Frame", nil, p)
						mm.p, mm.which = p, which
						mm:SetBackdrop(backdrop)
						mm:SetBackdropColor(0, 1, 0, 0.7)
						mm:SetFrameStrata("DIALOG")
						mm:SetPoint(p1, p, rp1, x1, y1)
						mm:SetPoint(p2, p, rp2, x2, y2)
						mm:EnableMouse(true)
						mm:SetMovable(true)
						mm:RegisterForDrag("LeftButton")
						mm:SetScript("OnMouseUp", function(this, a1) if a1 == "RightButton" then StellarBars.ShowOptions() end end)
						mm:SetScript("OnDragStart", function(this)
							if InCombatLockdown() then return end
							this.ismoving = true
							this.px, this.py = this.p:GetCenter()
							this.p:StartMoving()
						end)
						mm:SetScript("OnDragStop", function(this)
							if not this.ismoving then return end
							this.ismoving = nil
							this.p:StopMovingOrSizing()
							local nx, ny = this.p:GetCenter()
							db[this.which.."x"] = floor(0.5 + db[this.which.."x"] + (nx - this.px)*db.scale)
							db[this.which.."y"] = floor(0.5 + db[this.which.."y"] + (ny - this.py)*db.scale)
							UpdatePositions()
						end)
						return mm
					end
					mainmover = CreateMover(MainMenuBar, "main", "TOPLEFT", "BOTTOMLEFT", 0, 110, "BOTTOMRIGHT", "BOTTOMRIGHT", 0, 0)
					sidemover = CreateMover(MultiBarRight, "side", "TOPLEFT", "TOPRIGHT", -82, 2, "BOTTOMRIGHT", "BOTTOMRIGHT", 2, 0)
				end
				StellarBars.unlock = not StellarBars.unlock
				MultiBarRight:SetMovable(StellarBars.unlock)
				MainMenuBar:SetMovable(StellarBars.unlock)
				mainmover[StellarBars.unlock and "Show" or "Hide"](mainmover)
				sidemover[StellarBars.unlock and "Show" or "Hide"](sidemover)
			elseif a1 == "resetpos" then
				db.mainx, db.mainy, db.sidex, db.sidey = 0, 0, 0, 0
				UpdatePositions()
			else
				db[a1] = not db[a1]
				print("|cff00ff00StellarBars|r: This setting may require a reload to take effect.")
			end
		end
		local function SetSelect(b, a1)
			if InCombatLockdown() and (a1 == "scale" or a1 == "skin") then
				return print("|cff00ff00StellarBars|r: Unable to change this setting while in combat.")
			end
			db[a1] = tonumber(b.value) or b.value
			local level, num = strmatch(b:GetName(), "DropDownList(%d+)Button(%d+)")
			level, num = tonumber(level) or 0, tonumber(num) or 0
			for i = 2, level, 1 do
				for j = 1, UIDROPDOWNMENU_MAXBUTTONS, 1 do
					local b = _G["DropDownList"..i.."Button"..j.."Check"]
					if b and i == level and j == num then
						b:Show()
					elseif b then
						b:Hide()
					end
				end
			end
			if lbf and a1 == "skin" then
				lbfgroup:Skin(db.skin, true, true)
			else
				UpdateLook()
			end
		end
		local function SetColor(a1)
			local r, g, b, a
			if a1 then
				local pv = ColorPickerFrame.previousValues
				r, g, b, a = pv.r, pv.g, pv.b, 1 - pv.opacity
			else
				r, g, b = ColorPickerFrame:GetColorRGB()
				a = 1 - OpacitySliderFrame:GetValue()
			end
			db.r, db.g, db.b, db.a = r, g, b, a
			StellarMiscBG:SetBackdropColor(r, g, b, a * 0.8)
			if lbf then
				local skinc = skin.Backdrop.Color
				skinc[1], skinc[2], skinc[3], skinc[4] = r, g, b, a
				if db.skin == "StellarBars" then
					lbfgroup:Skin(db.skin, true, true)
				end
			else
				for _,value in ipairs(buttons) do
					for i = 0, 12, 1 do
						local butt = _G[format(value, i)]
						local sb = butt and butt.sbbutton
						if sb then sb:SetBackdropColor(r, g, b, a) end
					end
				end
				MainMenuBarBackpackButton.sbbutton:SetBackdropColor(r, g, b, a)
			end
		end
		local function AddButton(level, text, keepshown)
			info.text = text
			info.keepShownOnClick = keepshown
			UIDropDownMenu_AddButton(info, level)
			wipe(info)
		end
		local function AddToggle(level, text, value)
			info.arg1 = value
			info.func = Set
			if value == "unlock" then
				info.checked = StellarBars.unlock
			else
				info.checked = db[value]
			end
			AddButton(level, text, 1)
		end
		local function AddExecute(level, text, arg1, arg2)
			info.arg1 = arg1
			info.arg2 = arg2
			info.func = Set
			AddButton(level, text, 1)
		end
		local function AddList(level, text, value)
			info.value = value
			info.hasArrow = true
			info.func = HideCheck
			AddButton(level, text, 1)
		end
		local function AddSelect(level, text, arg1, value)
			info.arg1 = arg1
			info.func = SetSelect
			info.value = value
			if tonumber(value) then
				if floor(100 * tonumber(value)) == floor(100 * tonumber(db[arg1] or -1)) then
					info.checked = true
				end
			else
				info.checked = db[arg1] == value
			end
			AddButton(level, text, 1)
		end
		local function AddFakeSlider(lvl, value, minv, maxv, step, tbl)
			local cvalue = 0
			local dbv = db[value]
			if type(dbv) == "string" and tbl then
				for i, v in ipairs(tbl) do
					if dbv == v then
						cvalue = i
						break
					end
				end
			else
				cvalue = dbv or ((maxv - minv) / 2)
			end
			local adj = (offsetvalue == value and offsetcount) or 0
			local starti = max(minv, cvalue - (7 - adj) * step)
			local endi = min(maxv, cvalue + (8 + adj) * step)
			if starti == minv then
				endi = min(maxv, starti + 16 * step)
			elseif endi == maxv then
				starti = max(minv, endi - 16 * step)
			end
			if starti > minv then
				AddExecute(lvl, "--", "less", value)
			end
			if tbl then
				for i = starti, endi, step do
					AddSelect(lvl, tbl[i], value, tbl[i])
				end
			else
				local fstring = (step >= 1 and "%d") or (step >= 0.1 and "%.1f") or "%.2f"
				for i = starti, endi, step do
					AddSelect(lvl, format(fstring, i), value, i)
				end
			end
			if endi < maxv then
				AddExecute(lvl, "++", "more", value)
			end
		end
		StellarBarsDD.initialize = function(self, level)
			if level == 1 then
				info.isTitle = true
				AddButton(level, "|cffffff22Stellar|r|cff88ff88Bars|r")
				AddList(level, "Scale", "scale")
				AddList(level, "Opacity", "alpha")
				if lbf then
					AddList(level, "Skin", "skin")
				end
				
				info.hasColorSwatch = true
				info.hasOpacity = 1
				info.r, info.g, info.b, info.opacity = db.r, db.g, db.b, 1 - (db.a or 1)
				info.swatchFunc, info.opacityFunc, info.cancelFunc = SetColor, SetColor, SetColor
				info.value = "bgcolor"
				info.func = UIDropDownMenuButton_OpenColorPicker
				AddButton(level, "Backdrop Color", nil)
				
				AddList(level, "Exp. Texture", "texture")
				AddList(level, "Button Font", "font")
				
				AddToggle(level, "Out-of-Range Coloring", "oor")
				AddToggle(level, "Right-Click Self-Cast", "selfcast")
				AddToggle(level, "Reset Positions", "resetpos")
				AddToggle(level, "Unlock", "unlock")
			elseif level == 2 then
				local sub = UIDROPDOWNMENU_MENU_VALUE
				if sub == "font" or sub == "texture" then
					local t = smed:List(sub == "texture" and "statusbar" or sub)
					AddFakeSlider(level, sub, 1, #t, 1, t)
				elseif sub == "skin" then
					local i = 0
					lbf.sblist = lbf.sblist or { }
					for k, v in pairs(lbf:ListSkins()) do
						i = i + 1
						lbf.sblist[i] = k
					end
					AddFakeSlider(level, sub, 1, i, 1, lbf.sblist)
				elseif sub == "scale" then
					AddFakeSlider(level, sub, 0.3, 2, 0.02)
				elseif sub == "alpha" then
					AddFakeSlider(level, sub, 0, 1, 0.1)
				end
			end
		end
	end
	ToggleDropDownMenu(1, nil, StellarBarsDD, "cursor")
end